#pragma once
#include <iostream>
#include <string>
#include "InetAddr.hpp"
#include "Log.hpp"
#include "Socket.hpp"
#include "Protocol.hpp"
#include "NetCal.hpp"

using namespace log_ns;
using namespace socket_ns;
using namespace protocol_ns;

// 提供io服务，需要将对应的信息反序列化，然后执行，接着加上报头，然后继续序列化
// 然后将数据发送出去
class IOService {
public:
    IOService() {}

    void IOForword(calculate_t cal, ScokSPtr socket, InetAdrr& who) {
        // 将读和写包装起来
        while (true) {
            // 开始读和写
            std::string packages_stream;
            // LOG(INFO, "the sockfd: %d\n", sockfd);
            int n = socket->Recv(&packages_stream);
            if (n <= 0) {
                LOG(WARNING, "client %s quit or read error\n", who.AddrString().c_str());
                break;
            } else {
                // 在这里处理信息
                // 1. 先将数据解码
                std::string jsonstr = Decode(packages_stream);
                if (jsonstr.empty()) continue;

                std::cout << "----------------------------------" << std::endl;
                // 将解码的数据打印出来
                std::cout << "jsonstr\n" << jsonstr << std::endl;

                // 2. 然后将数据反序列化
                std::shared_ptr<Request> Req = Factory::BuildRequest();
                Req->Deserialize(jsonstr);

                // 3. 开始运行处理数据
                std::shared_ptr<Responce> Resp = cal(Req);

                // 4. 运行处理完数据之后将数据序列化
                std::string anti_jsonstr = Resp->Serialize();
                // 将序列化后的数据打印出来
                std::cout << "anti_json\n" << anti_jsonstr << std::endl;

                // 5. 给序列化的数据加上报头
                std::string package = Encode(anti_jsonstr);

                // 6. 将数据发送出去
                socket->Send(package);
            }
        }
    }

    ~IOService() {}
};